package server

import (
	"context"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"longmen/server/config/global"
	global2 "longmen/server/config/global"
	"longmen/server/internal/api"
	"longmen/server/internal/rpc/tencentim/chat"
	"longmen/server/internal/rpc/tencentim/room_event"
	"longmen/server/internal/services/nami/services"
	"longmen/server/internal/services/nami/utils"
	"longmen/server/pkg/common/api_models"
	_const "longmen/server/pkg/common/helper/const"
	string2 "longmen/server/pkg/common/helper/string"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/common/sdk/tx"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/db_live"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_guess"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"longmen/server/pkg/protobuf"
	"net"
	"sort"
	"time"

	"github.com/jinzhu/copier"
	"github.com/spf113/cast"

	"gorm.io/gorm"
)

// 热门直播
func (s *Server) HotLive(ctx context.Context, req *protobuf.HotLiveReq) (*protobuf.HotLiveResp, error) {
	var (
		tagQuery []*models_main.ConfigTag
		lives    []*models_live.Live
		err      error
		hotLives []*protobuf.Live
	)

	lives, _ = cache.GetInstance().QueryLiveByCatAndStatus(0, 0, 1, 1, 8, true)
	//lives, err = repository.GetLivesParam(map[string]interface{}{"status": 1}, "hot desc", 1, 8)
	if err != nil {
		return nil, err
	}

	tagQuery, _ = cache.GetAllTagCache()
	userArea, _ := mysql.GetIpToArea(req.ClientIp)

	var tempLiveIDs []int64
	for _, v := range lives {
		if v.Ticket > 0 {
			tempLiveIDs = append(tempLiveIDs, v.Liveid)
		}
	}

	var ticketLogs []models_live.LiveTicketLog
	if req.Uid > 0 && len(tempLiveIDs) > 0 {
		ticketLogs = db_live.TicketINLives(int(req.Uid), tempLiveIDs)
	}
	mGuess, _ := cache.GetGuessList()
	for _, v := range lives {
		// 检查屏蔽库是否返回动画直播
		v = db_live.Blocked(userArea, v)
		if v.PlayFromSource != 1 {
			v.PullUrl = tx.CreateLiveUrl(tx.HostFLV, v.Stream, 0)[0]
			v.PullFlvUrl = tx.CreateLiveUrl(tx.HostFLV, v.Stream, 0)[0]
			v.PullRtmpUrl = tx.CreateLiveUrl(tx.HostRTMP, v.Stream, 0)[0]
			v.PullM3u8Url = tx.CreateLiveUrl(tx.HostHLS, v.Stream, 0)[0]
			v.PullWebRTC = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]

			if v.EnableWebrtc == 1 {
				v.PullUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullFlvUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullRtmpUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullM3u8Url = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
			}
		} else {
			if v.Category != tx.RePlayType {
				v.Platform = 0 //客户端判断该值为3时，切换点播播放器
			}
			v.PullFlvUrl2 = v.PullUrl
			v.PullRtmpUrl = v.PullUrl
			v.PullM3u8Url = v.PullUrl
		}
		tagInfo := getTag(v.Tag, tagQuery)
		ticketPaid := 2
		//是否支付门票
		if len(ticketLogs) > 0 && v.Ticket > 0 {
			for _, l := range ticketLogs {
				if l.Liveid == v.Liveid {
					ticketPaid = 1
				}
			}
		}
		iGuessTag := 0
		if mGuess != nil {
			if liveId, ok := (*mGuess)[v.Anchorid]; ok && (liveId == v.Liveid) {
				iGuessTag = 1
			}
		}
		if req.Platform == _const.TERMINAL_PC {
			v.Thumb = v.Thumb + "?" + _const.ThumbCropUrl + _const.PCThumbSize
		} else {
			v.Thumb = v.Thumb + "?" + _const.ThumbCropUrl + _const.MobileThumSize
		}
		live := &protobuf.Live{
			AnchorAvatar:      v.AnchorAvatar,
			Anchorid:          uint32(v.Anchorid),
			Hot:               uint32(v.Hot),
			AnchorName:        v.AnchorName,
			Title:             v.Title,
			Thumb:             v.Thumb,
			PullUrl:           v.PullUrl,
			PullFlvUrl:        v.PullFlvUrl,
			Animation:         int32(v.Animation),
			ThumbY:            v.ThumbY,
			CategoryId:        int32(v.Categoryid),
			MatchId:           int64(v.Matchid),
			PullRtmpUrl:       v.PullRtmpUrl,
			PullM3U8Url:       v.PullM3u8Url,
			Ticket:            int32(v.Ticket),
			TicketPaid:        int32(ticketPaid),
			Liveid:            v.Liveid,
			GuessTag:          int32(iGuessTag),
			Platform:          v.Platform,
			PlayFromSource:    v.PlayFromSource,
			ReplyVideo:        v.ReplyVideo,
			WatermarkPosition: v.WatermarkPosition,
			PullWebrtc:        v.PullWebRTC,
		}
		if tagInfo != nil {
			live.TagTitle = tagInfo.Title
			live.TagColor = tagInfo.Color
			live.TagPoint = int32(tagInfo.Point)
			live.TagType = int32(tagInfo.Type)
		}
		hotLives = append(hotLives, live)
	}
	return &protobuf.HotLiveResp{HotLive: hotLives}, nil
}

/**
 * @Author admin
 * @Description //某一赛事直播列表
 * @version: v1.8.0
 * @Date 10:39 2022/7/20
 * @Param
 * @return
 **/
func (s *Server) MatchLiveList(ctx context.Context, req *protobuf.LiveListReq) (*protobuf.LiveListResp, error) {

	lives, err := db_live.GetMatchLivesParam(int(req.Categoryid), cast.ToInt(req.GetUid()), req.ClientIp, int(req.Page), int(req.Size))
	var attentAnchorIds []int //关注的主播
	if req.GetUid() > 0 {
		attentAnchorIds = cache.GetUserAttentAnchorIds(int(req.GetUid()))
	}

	for k, v := range lives {
		for _, id := range attentAnchorIds {
			if id == int(v.Anchorid) {
				lives[k].Isattent = 1
				break
			}
		}
		lives[k].Hot = uint32(cache.GetFansCount(int(v.Anchorid)))
		global2.Log.Debugf("主播id:%v,粉丝数:%v", v.Anchorid, lives[k].Hot)
	}
	sort.Slice(lives, func(i, j int) bool {
		return lives[i].Hot > lives[i].Hot
	})
	if err != nil {
		return nil, err
	}
	return &protobuf.LiveListResp{LiveList: lives}, nil
}

// 直播列表
func (s *Server) LiveList(ctx context.Context, req *protobuf.LiveListReq) (*protobuf.LiveListResp, error) {
	var (
		//err       error
		//count     int64
		//lives     []*models.Live
		tagQuery  []*models_main.ConfigTag
		hotLives  = make([]*protobuf.Live, 0)
		condition = map[string]interface{}{
			"status": 1,
		}
	)

	if req.Categoryid > 0 {
		condition["categoryid"] = req.Categoryid
	}
	if req.Cateid > 0 {
		condition["category"] = req.Cateid
	}

	/*if lives, err = repository.GetLivesParam(condition, "hot desc", int(req.Page), int(req.Size)); err != nil {
		return nil, err
	}*/
	//lives, counts := cache.GetInstance().QueryLiveByCatAndStatusWithCateExcept(int(req.Categoryid), int(req.Cateid), 1, int(req.Page), int(req.Size), true, req.Channel, req.Platform)
	lives, counts := cache.GetInstance().QueryLiveByCatAndStatus(int(req.Categoryid), int(req.Cateid), 1, int(req.Page), int(req.Size), true)

	tagQuery, _ = cache.GetAllTagCache()
	// userArea, _ := mysql.GetIpToArea(req.ClientIp)

	// var tempLiveIDs []int64
	// for _, v := range lives {
	// 	if v.Ticket > 0 {
	// 		tempLiveIDs = append(tempLiveIDs, v.Liveid)
	// 	}
	// }

	// var ticketLogs []models_live.LiveTicketLog
	// if req.Uid > 0 && len(tempLiveIDs) > 0 {
	// 	ticketLogs = db_live.TicketINLives(cast.ToInt(req.Uid), tempLiveIDs)
	// }
	mGuess, _ := cache.GetGuessList()
	for _, v := range lives {
		// 检查屏蔽库是否返回动画直播
		// v = db_live.Blocked(userArea, v)

		tagInfo := getTag(v.Tag, tagQuery)
		pullFlvUrl := v.PullFlvUrl
		if v.PlayFromSource != 1 {
			v.PullUrl = tx.CreateLiveUrl(tx.HostFLV, v.Stream, 0)[0]
			pullFlvUrl = tx.CreateLiveUrl(tx.HostFLV, v.Stream, 0)[0]
			v.PullRtmpUrl = tx.CreateLiveUrl(tx.HostRTMP, v.Stream, 0)[0]
			v.PullM3u8Url = tx.CreateLiveUrl(tx.HostHLS, v.Stream, 0)[0]
			v.PullWebRTC = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
			v.PullFlvUrl2 = tx.CreateLiveUrl(tx.HostFLV, v.Stream+global.Config.GetString("livespeed1"), 0)[0]

			if v.EnableWebrtc == 1 {
				v.PullUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				pullFlvUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullRtmpUrl = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullM3u8Url = tx.CreateLiveUrl(tx.HostUDP, v.Stream, 0)[0]
				v.PullFlvUrl2 = tx.CreateLiveUrl(tx.HostFLV, v.Stream+global.Config.GetString("livespeed1"), 0)[0]
			}
		} else {
			if v.Category != tx.RePlayType {
				v.Platform = 0 //客户端判断该值为3时，切换点播播放器
			}
			v.PullFlvUrl2 = v.PullUrl
			v.PullRtmpUrl = v.PullUrl
			v.PullM3u8Url = v.PullUrl
		}

		ticketPaid := cast.ToInt(2)
		//是否支付门票
		// if len(ticketLogs) > 0 && v.Ticket > 0 {
		// 	for _, l := range ticketLogs {
		// 		if l.Liveid == v.Liveid {
		// 			ticketPaid = 1
		// 		}
		// 	}
		// }
		iGuessTag := 0
		if mGuess != nil {
			if liveId, ok := (*mGuess)[v.Anchorid]; ok && (liveId == v.Liveid) {
				iGuessTag = cast.ToInt(1)
			}
		}
		if req.Platform == 0 {
			v.Thumb = v.Thumb + "?" + _const.ThumbCropUrl + _const.PCThumbSize
		} else {
			v.Thumb = v.Thumb + "?" + _const.ThumbCropUrl + _const.MobileThumSize
		}
		live := &protobuf.Live{
			Anchorid:          uint32(v.Anchorid),
			Hot:               uint32(v.Hot),
			AnchorName:        v.AnchorName,
			Title:             v.Title,
			Thumb:             v.Thumb,
			PullUrl:           v.PullUrl,
			PullFlvUrl:        pullFlvUrl,
			Animation:         int32(v.Animation),
			ThumbY:            v.ThumbY,
			AnchorAvatar:      v.AnchorAvatar,
			CategoryId:        int32(v.Categoryid),
			MatchId:           int64(v.Matchid),
			TagId:             v.Tag,
			TagTitle:          "",
			TagColor:          "",
			TagPoint:          0,
			TagType:           0,
			PullM3U8Url:       v.PullM3u8Url,
			PullRtmpUrl:       v.PullRtmpUrl,
			Ticket:            int32(v.Ticket),
			TicketPaid:        int32(ticketPaid),
			Liveid:            v.Liveid,
			GuessTag:          int32(iGuessTag),
			Platform:          v.Platform,
			PlayFromSource:    v.PlayFromSource,
			ReplyVideo:        v.ReplyVideo,
			WatermarkPosition: v.WatermarkPosition,
			PullWebrtc:        v.PullWebRTC,
			PullFlvUrl2:       v.PullFlvUrl2,
		}
		if tagInfo != nil {
			live.TagTitle = tagInfo.Title
			live.TagColor = tagInfo.Color
			live.TagPoint = int32(tagInfo.Point)
			live.TagType = int32(tagInfo.Type)
		}

		hotLives = append(hotLives, live)
	}

	return &protobuf.LiveListResp{LiveList: hotLives, Total: int64(counts)}, nil
}

// 写入访问记录
func (s *Server) LiveVisitRecord(ctx context.Context, req *protobuf.LiveVisitRecordReq) (*protobuf.LiveVisitRecordResp, error) {
	return db_live.LiveVisitRecord(req.Liveid, req.UserId, req.Platform)
}

// 用户历史访问记录
func (s *Server) LiveVisitList(ctx context.Context, req *protobuf.LiveVisitReq) (*protobuf.LiveVisitResp, error) {
	return db_live.LiveVisitList(req.UserId, int(req.Page), int(req.Size), int(req.Status))
}

// 清除用户访问记录
func (s *Server) LiveVisitClean(ctx context.Context, req *protobuf.LiveVisitCleanReq) (*protobuf.LiveVisitRecordResp, error) {
	return db_live.LiveVisitClean(req.UserId)
}

func (s *Server) UserBackpack(ctx context.Context, req *protobuf.UserBackpackReq) (*protobuf.UserBackpackResp, error) {
	return db_live.UserBackpack(req.UserId)
}

func (s *Server) UserBackpackSetSelected(ctx context.Context, req *protobuf.UserBackpackSetSelectedReq) (*protobuf.UserBackpackSetSelectedResp, error) {
	resp, err := db_live.UserBackpackSetSelected(req.GetType(), req.GetUserId(), req.GetIds(), req.GetSel())
	if err == nil {
		_ = cache.ChangePropChannel(int(req.GetUserId()))
	}
	return resp, err
}

// 修改房间热度
func (s *Server) UpdateBaseHeat(ctx context.Context, req *protobuf.UpdateBaseHeatReq) (*protobuf.UpdateBaseHeatResp, error) {
	room_event.HandlingRoomHeat(int(req.Anchorid))
	return &protobuf.UpdateBaseHeatResp{
		Status: 1,
	}, nil
}

// 主播报表
func (s *Server) AnchorLiveStat(ctx context.Context, req *protobuf.LiveStatReq) (*protobuf.LiveStatSummaryResp, error) {
	return db_live.AnchorLiveStat(req)
}

// 我的直播历史
func (s *Server) LiveHistory(ctx context.Context, req *protobuf.LiveHistoryReq) (*protobuf.LiveHistoryResp, error) {
	var lh []*protobuf.LiveHistory
	st, _ := utils.OneDayRange2Unix(req.StartDate)
	_, et := utils.OneDayRange2Unix(req.EndDate)
	err := global2.Live().Model(&models_live.LiveHistory{}).
		Select("id, thumb, anchorid, liveid, end_stamp, start_stamp, new_fans_count as new_fans, barrage_time_count as text_num, title, start_stamp as timehelper").
		Where("anchorid=? and end_stamp>=? and end_stamp<=?", req.Id, st, et).
		Scan(&lh).Error
	if err != nil {
		return &protobuf.LiveHistoryResp{
			LiveHisgory: lh,
		}, errors.New("数据异常")
	}

	// var resp []*pb.LiveHistory
	var tempLiveIDs []int64

	for _, v := range lh {
		tempLiveIDs = append(tempLiveIDs, v.Liveid)
	}

	var giftNum []api_models.LiveIDGiftNum
	var incomes []api_models.LiveIDIncome
	var visitors []api_models.LiveIDVisitorNum
	if len(tempLiveIDs) > 0 {
		giftNum = db_live.AnchorLiveIDGiftNum(tempLiveIDs)
		incomes = db_live.AnchorLiveIDsIncome(tempLiveIDs)
		visitors = db_live.AnchorLiveIDVisitorNum(tempLiveIDs)
	}

	for idx, v := range lh {
		v.Duration = v.EndStamp - v.StartStamp
		if len(giftNum) > 0 {
			for _, g := range giftNum {
				if g.Liveid == v.Liveid {
					lh[idx].GiftNum += 1
				}
			}
		}
		if len(incomes) > 0 {
			for _, g := range incomes {
				if g.Liveid == v.Liveid {
					if g.SpendType == 2 {
						lh[idx].Diamond = int64(g.Income)
					} else {
						lh[idx].OtherGift = int64(g.EagleDiamond)
					}

				}
			}
		}
		if len(visitors) > 0 {
			for _, g := range visitors {
				if g.Liveid == v.Liveid {
					lh[idx].Visitor = g.VisitorNum
				}
			}
		}

	}

	return &protobuf.LiveHistoryResp{
		LiveHisgory: lh,
	}, nil
}

// 我的观众
func (s *Server) LiveVisitor(ctx context.Context, req *protobuf.LiveVisitorReq) (*protobuf.LiveVisitorResp, error) {
	var lv []*protobuf.LiveVisitor
	var ls *models_live.LiveHistory
	err := global2.Live().Model(&models_live.LiveHistory{}).Where("anchorid=?", req.Id).Order("id desc").Limit(1).Find(&ls).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}

	model := global2.Live().Model(&models_live.LiveStreamHistory{}).
		Select("*").Where("anchorid=?", req.Id)
	if req.LastTime {
		model.Where("liveid=?", ls.Liveid)
	} else {
		st, _ := utils.OneDayRange2Unix(req.StartDate)
		_, et := utils.OneDayRange2Unix(req.EndDate)
		model.Where("last_visit_time>=? and last_visit_time<=?", st, et)
	}

	err = model.Order("id desc").Limit(100).Group("user_id").
		// Offset(offset * size).
		// Limit(size).
		Scan(&lv).Error
	if err != nil {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}

	var ids []int

	for _, v := range lv {
		ids = append(ids, int(v.UserId))
	}

	var user []*models_main.User
	err = global2.GetX().Model(&models_main.User{}).Where("id in ?", ids).Find(&user).Error
	if err != nil {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}

	for idx, v := range lv {
		for _, u := range user {
			if v.UserId == int64(u.Id) {
				lv[idx].Avatar = u.Avatar
				lv[idx].Name = u.NickName
			}
		}
	}

	var fans []*models_main.AnchorFans
	err = global2.Live().Model(&models_main.AnchorFans{}).Where("fansid in ?", ids).Find(&fans).Error
	if err != nil {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}

	for idx, v := range lv {
		for _, f := range fans {
			if v.UserId == int64(f.Fansid) {
				lv[idx].IsFans = 1
			} else {
				lv[idx].IsFans = 0
			}
		}
	}

	// 克拉
	type Spend struct {
		FUID  int `json:"f_uid"`
		Spend int `json:"spend"`
	}
	var spend []Spend
	giftModel := global2.GetR().Model(&models_main.UserProfit{}).Select("f_uid, sum(coin_count) as spend").Where("coin_type=2 and type=1 and consume_type=5 and uid=?", req.Id)
	if req.LastTime {
		giftModel.Where("liveid=?", ls.Liveid)
	} else {
		giftModel.Where("create_time>=? and create_time<=?", req.StartDate, req.EndDate+" 23:59:59")
	}
	if req.LastTime {
		giftModel.Where("liveid=?", ls.Liveid)
	}
	err = giftModel.Group("f_uid").Scan(&spend).Error
	if err != nil {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}
	// 鹰钻
	var spend1 []Spend
	giftModel1 := global2.GetR().Model(&models_main.UserProfit{}).Select("f_uid, sum(coin_count) as spend").Where("coin_type=1 and type=1 and consume_type=5 and uid=?", req.Id)
	if req.LastTime {
		giftModel1.Where("liveid=?", ls.Liveid)
	} else {
		giftModel1.Where("create_time>=? and create_time<=?", req.StartDate, req.EndDate+" 23:59:59")
	}
	err = giftModel1.Group("f_uid").Scan(&spend1).Error
	if err != nil {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv,
		}, errors.New("数据异常")
	}

	for idx, v := range lv {
		for _, k := range spend {
			if v.UserId == int64(k.FUID) {
				lv[idx].Diamond = int64(k.Spend)
			}
		}

		for _, k := range spend1 {
			if v.UserId == int64(k.FUID) {
				lv[idx].OtherGift = int64(k.Spend)
			}
		}
	}

	// 冒泡排序 按克拉值
	if req.Sort == 2 {
		lv = bubbleSort(lv, "desc")
	}

	if req.Sort == 3 {
		lv = bubbleSort(lv, "asc")
	}
	start := req.Page - 1
	if int(start)*int(req.Size) > len(lv) {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: nil,
		}, nil
	}
	if len(lv) >= int(req.Page)*int(req.Size) {

		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv[start*req.Size : req.Page*req.Size],
		}, nil
	} else {
		return &protobuf.LiveVisitorResp{
			LiveVisitor: lv[start*req.Size:],
		}, nil
	}

}

func bubbleSort(arr []*protobuf.LiveVisitor, sort string) []*protobuf.LiveVisitor {
	length := len(arr)
	for i := 0; i < length; i++ {
		for j := 0; j < length-1-i; j++ {
			if sort == "asc" {
				if arr[j].Diamond > arr[j+1].Diamond {
					arr[j], arr[j+1] = arr[j+1], arr[j]
				}
			}
			if sort == "desc" {
				if arr[j].Diamond < arr[j+1].Diamond {
					arr[j], arr[j+1] = arr[j+1], arr[j]
				}
			}
		}
	}

	for idx, _ := range arr {
		if sort == "desc" {
			arr[idx].Order = int32(idx + 1)
		}

		if sort == "asc" {
			arr[idx].Order = int32(len(arr) - idx)

		}
	}
	return arr
}

// getTag 检索标签信息
func getTag(tagID int64, tagQuery []*models_main.ConfigTag) *models_main.ConfigTag {
	if tagQuery == nil {
		return nil
	}

	for _, tag := range tagQuery {
		if int64(tag.Id) == tagID {
			tag.Operator = ""
			return tag
		}
	}

	return nil
}
func (s *Server) EndLive(ctx context.Context, req *protobuf.EndLiveReq) (*protobuf.EndLiveResp, error) {
	err := services.EndLive(int(req.AnchorId))

	if err != nil {
		return &protobuf.EndLiveResp{
			Status: 0,
		}, err
	}

	return &protobuf.EndLiveResp{
		Status: 1,
	}, err
}

func (s *Server) TopUser(ctx context.Context, req *protobuf.TopUserReq) (*protobuf.TopUserResp, error) {
	var (
		err   error
		tu    []models_main.TopUser
		resp  []*protobuf.TopUser
		today = time.Now()
	)
	cacheKey := "TopUser" + fmt.Sprintf("%d%d", req.DateType, req.Type)

	check := global2.GetRds().Exists(cacheKey).Val()
	cache.GetCachedData(cacheKey, &resp)
	if check == 1 {
		return &protobuf.TopUserResp{
			TopUser: resp,
		}, err
	}

	switch req.DateType {
	case 1:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("day_fans_stat+modify_day_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		} else {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("day_diamond_stat+modify_day_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	case 2:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("week_fans_stat+modify_week_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
		if req.Type == 2 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("week_diamond_stat+modify_week_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
		if req.Type == 3 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("week_guess_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	case 3:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("month_fans_stat+modify_month_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		} else {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Format("2006-01-02")).Order("month_diamond_stat+modify_month_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	case 4:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Add(-24*time.Hour).Format("2006-01-02")).Order("day_fans_stat+modify_day_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		} else {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", today.Add(-24*time.Hour).Format("2006-01-02")).Order("day_diamond_stat+modify_day_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	case 5:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", utils.GetLastDayOfWeek(-1).Format("2006-01-02")).Order("week_fans_stat+modify_week_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		} else {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", utils.GetLastDayOfWeek(-1).Format("2006-01-02")).Order("week_diamond_stat+modify_week_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	case 6:
		if req.Type == 1 {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", utils.GetLastDayOfMonth(-1).Format("2006-01-02")).Order("month_fans_stat+modify_month_fans_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		} else {
			//order by
			err = global2.Live().Model(&models_main.TopUser{}).Where("date=?", utils.GetLastDayOfMonth(-1).Format("2006-01-02")).Order("month_diamond_stat+modify_month_diamond_stat desc").Limit(20).Find(&tu).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
		}
	}

	for _, v := range tu {
		// 统计总数
		var stat int64 = 0
		switch req.DateType {
		case 1:
			if req.Type == 1 {
				stat = int64(v.DayFansStat*11) + int64(v.ModifyDayFansStat)
			} else {
				stat = int64(v.DayDiamondStat) + int64(v.ModifyDayDiamondStat)
			}
		case 2:
			if req.Type == 1 {
				stat = int64(v.WeekFansStat*11) + int64(v.ModifyWeekFansStat)
			}
			if req.Type == 2 {
				stat = int64(v.WeekDiamondStat) + int64(v.ModifyWeekDiamondStat)
			}
			if req.Type == 3 {
				stat = int64(v.WeekGuessStat)
			}

		case 3:
			if req.Type == 1 {
				stat = int64(v.MonthFansStat*11) + int64(v.ModifyMonthFansStat)
			} else {
				stat = int64(v.MonthDiamondStat) + int64(v.ModifyMonthDiamondStat)
			}
		}

		// 拿用户信息
		user, err := s.GetUserInfo(ctx, &protobuf.GetUserInfoReq{Uid: uint64(v.Uid)})

		if err != nil {
			return &protobuf.TopUserResp{TopUser: resp}, err
		}

		// 是否开播或关注
		var isLive = 2
		var isFollow = 2
		if req.Type == 1 {
			//var checkLive int64 = 0

			uidLen := cache.GetInstance().CountLiveByCatAndStatus(0, 0, 1, v.Uid, 0)

			/*err := global.Live().Model(&models.Live{}).Where("anchorid=? and status=1", v.Uid).Count(&checkLive).Error
			if err != nil {
				return &pb.TopUserResp{TopUser: resp}, err
			}*/
			if len(uidLen) >= 1 {
				isLive = 1
			}

			var checkFollow int64 = 0
			err = global2.Live().Model(&models_main.AnchorFans{}).Where("anchorid=? and fansid=?", v.Uid, req.UserId).Count(&checkFollow).Error
			if err != nil {
				return &protobuf.TopUserResp{TopUser: resp}, err
			}
			if checkFollow >= 1 {
				isFollow = 1
			}
		}

		resp = append(resp, &protobuf.TopUser{
			Uid:      int64(v.Uid),
			Stat:     stat,
			Avatar:   user.Avatar,
			Level:    int32(user.Level),
			Nickname: user.NickName,
			NobleId:  int64(user.NobleId),
			IsLive:   int32(isLive),
			IsFollow: int32(isFollow),
		})
	}

	// 排序
	// length := len(resp)
	// for i := 0; i < length; i++ {
	// 	for j := 0; j < length-1-i; j++ {
	// 		if resp[j].Stat < resp[j+1].Stat {
	// 			resp[j], resp[j+1] = resp[j+1], resp[j]
	// 		}
	// 	}
	// }

	cache.SetCacheData(cacheKey, resp, 20*time.Second)

	return &protobuf.TopUserResp{
		TopUser: resp,
	}, err
}

/**
 * @Author admin
 * @Description //
 * @version: v1.8.0
 * @Date 16:47 2022/8/15
 * @Param
 * @return
 **/
func (s *Server) GetLiveSeoList(ctx context.Context, req *protobuf.Empty) (*protobuf.LiveSeoResp, error) {
	ret := &protobuf.LiveSeoResp{}
	if list, err := db_live.GetLiveSeoList(); err == nil {
		ret.List = list
	}
	return ret, nil
}

/**
 * @Author willi
 * @Description //使用背包
 * @Date 10:46 2022/9/9
 * @Param
 * @return
 **/
func (s *Server) UseBackPackProps(ctx context.Context, req *protobuf.UseBackPackPropsReq) (*protobuf.UseBackPackPropsResp, error) {
	ret := &protobuf.UseBackPackPropsResp{Code: 1}
	switch {
	case req.PropsType == 102:
		if db_main.UseBackPackProps(req.UserId, req.PropsId, req.PropsType) > 0 {
			if req.PropsType == 102 { //座骑
				nobles, err := db_main.GetNobleByPropsId(uint8(req.PropsId))
				if err == nil {
					chat.SetClientUserVip(int(req.UserId), int(nobles.Id)) //通过req.PropsId取得贵族id
				}

			}
			ret.Code = 0
		}
	}
	return ret, nil
}

func (s *Server) AdminPlaybackToLive(ctx context.Context, req *protobuf.AdminPlaybackToLiveReq) (*protobuf.AdminPlaybackToLiveResp, error) {
	ret := &protobuf.AdminPlaybackToLiveResp{}
	ret.Status = 1

	// 主播信息
	idx, err := db_live.GetIdle(global2.AutoLive.ReplayIDs)
	if err != nil {
		global2.Log.Errorf("AuthLive getIdle ERROR:%v", err)
		return nil, err
	}

	user, err := mysql.GetUserParam(map[string]interface{}{"id": idx})
	if err != nil {
		return nil, err
	}

	playbackData := &models_main.Video{}
	if err = global2.GetR().Model(&models_main.Video{}).Where("id = ?", req.Id).Find(&playbackData).Error; err != nil {
		global2.Log.Debugf("AdminPlaybackToLive err:%v", err)
		return nil, err
	}

	liveHistory, err := db_live.GetLiveHistoryParam(map[string]interface{}{"stream": playbackData.Stream})
	if err != nil {
		global2.Log.Debugf("AdminPlaybackToLive err:%v", err)
		return nil, err
	}
	if liveHistory.Stream == "" {
		global2.Log.Debugf("AdminPlaybackToLive err:%v", errors.New("stream null"))
		return nil, errors.New("stream null")
	}

	base := api.Controller{}
	base.Service.GetStreamInfo(user)

	var liveParams api_models.StartLiveReq
	liveParams.Title = liveHistory.Title
	liveParams.MatchId = int(liveHistory.Matchid)
	liveParams.Category = 100
	liveParams.Cateid = 112
	liveParams.Thumb = liveHistory.Thumb
	liveParams.SportType = liveHistory.SportType
	rt, err := base.Service.StartLive(&liveParams, user, &api_models.LivePlugins{
		LiveStatus:     int(cache.StartLive),
		Platform:       3,
		PlayFromSource: 1,
		ReplyVideo:     1,
		PullUrl:        playbackData.PlayURL,
		PullFlvUrl:     playbackData.PlayURL,
		SkipTime:       playbackData.SkipTime,
	})
	if err != nil {
		return nil, err
	}
	ret.Message = rt.Title
	return ret, nil
}

func (s *Server) LiveData(ctx context.Context, r *protobuf.LiveDataReq) (*protobuf.LiveDataResp, error) {
	/*if exist, err := models.GetBloom().Exists(models.ID, cast.ToString(r.Anchorid)); err != nil || !exist {
		return nil, errors.New("主播不存在:" + fmt.Sprint(exist))
	}*/
	anchorData, err := cache.GetUserFullInfo(int(r.Anchorid)) //repository.GetUserParam(map[string]interface{}{"id": r.Anchorid})
	if err != nil {
		return nil, err
	}

	var live *protobuf.LiveData
	var check int64
	live, check = cache.LiveData(int(r.Anchorid))
	if live.GetLiveid() == 0 {
		live.Anchorid = r.Anchorid
	}

	if check > 0 {
		live.TicketPaid = 2
		// if db_live.TicketINLive(int(r.Uid), live.Liveid) {
		// 	live.TicketPaid = 1
		// }
		ticketLiveFlag, err := db_live.TicketINLive(int(r.Uid), live.Liveid, cache.GetConfigPub().TicketSwitch)
		if err != nil {
			return nil, err
		}

		if ticketLiveFlag {
			live.TicketPaid = 1
		}
	}

	live.AnchorAvatar = anchorData.Avatar
	live.AnchorName = anchorData.NickName

	// 判断门票入场信息
	// if models_live.Ticket > 0 {
	// 	if r.Uid == 0 {
	// 		return nil, errors.New("本场直播需要门票观看,请登录后继续")
	// 	}
	// 	checked := repository.TicketINLive(r.Uid, models_live.Liveid)
	// 	if !checked {
	// 		var ticket = &models.LiveTicketLog{
	// 			UID:       r.Uid,
	// 			AnchorID:  r.Anchorid,
	// 			Liveid:    models_live.Liveid,
	// 			Ticket:    models_live.Ticket,
	// 			CreatedAt: timehelper.Now().Unix(),
	// 		}

	// 		err = repository.TicketLog(ticket)
	// 		if err != nil {
	// 			return nil, err
	// 		}
	// 	}

	// }

	cateName := ""
	var userArea *api_models.GetIpSearchResp
	// 后台修改主播资料能及时在直播间生效
	if check > 0 {
		// if global2.Config.GetInt("area_check") == 1 {
		// 	userArea, _ = mysql.GetIpToArea(r.ClientIp)
		// 	// 检查屏蔽库是否返回动画直播
		// 	live = db_live.Blocked(userArea, live)
		// }
		if live.PlayFromSource == 1 {
			if live.Category != tx.RePlayType {
				live.Platform = 0 //客户端判断该值为3时，切换点播播放器
			}
			live.PullFlvUrl2 = live.PullUrl
			live.Pull_RtmpUrl = live.PullUrl
			live.PullM3U8Url = live.PullUrl
			live.PullM3U8Url2 = live.PullUrl
		} else {

			live.PullUrl = tx.CreateLiveUrl(tx.HostFLV, live.Stream, 0)[0]
			live.PullFlvUrl = tx.CreateLiveUrl(tx.HostFLV, live.Stream, 0)[0]
			live.Pull_RtmpUrl = tx.CreateLiveUrl(tx.HostRTMP, live.Stream, 0)[0] //---取rtmp的源
			live.PullM3U8Url = tx.CreateLiveUrl(tx.HostHLS, live.Stream, 0)[0]   //---取m3u8的源
			live.PullFlvUrl2 = tx.CreateLiveUrl(tx.HostFLV, live.Stream+global.Config.GetString("livespeed1"), 0)[0]
			live.PullM3U8Url2 = tx.CreateLiveUrl(tx.HostHLS, live.Stream+global.Config.GetString("livespeed1"), 0)[0] //---取m3u8的源

			if live.EnableWebrtc == 1 {
				live.PullUrl = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
				live.PullFlvUrl = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
				live.PullFlvUrl2 = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
				live.Pull_RtmpUrl = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
				// live.PullM3U8Url = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0] 保留一条
				// live.PullM3U8Url2 = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
				live.PullWebrtc = tx.CreateLiveUrl(tx.HostUDP, live.Stream, 0)[0]
			}
		}
		param := map[string]interface{}{
			"id": live.Categoryid,
		}
		cates, err := db_live.GetLiveCategoryParam(param, "")

		if err == nil && len(cates) > 0 {
			cateName = cates[0].Title
		}
	}

	//global2.Log.Debugf("GetLivePageData detail :%+v", live)

	//anchor, err := s.GetAnchor(r.Anchorid)
	//if err != nil {
	//	return nil, fmt.Errorf("%s%s", common.Convert(fName), err.Error())
	//}
	var anchor protobuf.Anchor
	anchor.NickName = anchorData.NickName
	anchor.Id = r.Anchorid
	anchor.Avatar = anchorData.Avatar
	anchor.FansNum = int64(cache.GetFansCount(int(r.Anchorid)))
	anchor.Profile = &protobuf.Profile{
		Uid:           int64(anchorData.Id),
		Age:           0,
		Gender:        0,
		Career:        "",
		Height:        0,
		Weight:        0,
		City:          "",
		Birthday:      "",
		Constellation: "",
		Signature:     "",
		Photos:        "",
	}

	if r.Uid > 0 {
		attentedIds := cache.GetUserAttentAnchorIds(int(r.Uid))
		global2.Log.Debugf("attentedIds:%v\n", attentedIds)
		if string2.IntIsInSlice(attentedIds, int(r.Anchorid)) {
			anchor.Isattent = 1
		}

		// user, err := mysql.GetUserParam(map[string]interface{}{"id": r.Uid})

		// if err == nil {
		// 	// 渠道统计
		// 	if user.RegSourceId != "" {
		// 		buff, err := json.Marshal(user)
		// 		if err != nil {
		// 			global.Log.Errorf("set source stat error[%+v]: ", err)
		// 		} else {
		// 			_, err := global.GetNats().PublishAsync(util.STAT_USER_ACTIVE_CHANNEL, buff, nil)
		// 			if err != nil {
		// 				global.Log.Errorf("Nats publish chanel %s", err.Error())
		// 			}
		// 		}

		// 		err = global2.PublishChannelStats.Send(publisher2.ActiveChannelStats, user)
		// 		if err != nil {
		// 			global2.Log.Errorf("Nats publish chanel %s", err.Error())
		// 		}
		// 	}
		// }
	}
	var recLives = []*protobuf.LiveData{}
	// if check <= 0 {
	recLives = cache.RecLives()
	ids := make([]int, 0)
	for idx := range recLives {
		ids = append(ids, int(recLives[idx].Anchorid))
	}

	anchorMap, err := getAnchors(0, ids, "", 0, 0)
	if err != nil {
		return nil, fmt.Errorf("rpc:LiveData:%s", err.Error())
	}

	for idx := range recLives {
		if _, ok := anchorMap[int(recLives[idx].Anchorid)]; ok {
			// recLives[idx].Anchor = anchorMap[recLives[idx].Anchorid]
			recLives[idx].Anchor = &protobuf.Anchor{
				Id:        int64(anchorMap[int(recLives[idx].Anchorid)].Id),
				NickName:  anchorMap[int(recLives[idx].Anchorid)].NickName,
				UserLevel: int32(anchorMap[int(recLives[idx].Anchorid)].UserLevel),
				Avatar:    anchorMap[int(recLives[idx].Anchorid)].Avatar,
				IsAnchor:  int32(anchorMap[int(recLives[idx].Anchorid)].IsAnchor),
				// VipDate:     anchorMap[int(recLives[idx].Anchorid)].VipDate.Format(time.DateTime),
				VipDate:     "",
				VipLevel:    int32(anchorMap[int(recLives[idx].Anchorid)].VipLevel),
				AnchorLevel: int32(anchorMap[int(recLives[idx].Anchorid)].AnchorLevel),
				Point:       anchorMap[int(recLives[idx].Anchorid)].Point,
				Profile: &protobuf.Profile{
					Uid:           int64(anchorMap[int(recLives[idx].Anchorid)].Profile.Uid),
					Age:           int32(anchorMap[int(recLives[idx].Anchorid)].Profile.Age),
					Gender:        int32(anchorMap[int(recLives[idx].Anchorid)].Profile.Gender),
					Career:        anchorMap[int(recLives[idx].Anchorid)].Profile.Career,
					Height:        int32(anchorMap[int(recLives[idx].Anchorid)].Profile.Height),
					Weight:        int32(anchorMap[int(recLives[idx].Anchorid)].Profile.Weight),
					City:          anchorMap[int(recLives[idx].Anchorid)].Profile.City,
					Birthday:      anchorMap[int(recLives[idx].Anchorid)].Profile.Birthday,
					Constellation: anchorMap[int(recLives[idx].Anchorid)].Profile.Constellation,
					Signature:     anchorMap[int(recLives[idx].Anchorid)].Profile.Signature,
					// Photos:        *anchorMap[int(recLives[idx].Anchorid)].Profile.Photos,
					Photos: "",
				},
				Isattent:       int32(anchorMap[int(recLives[idx].Anchorid)].Isattent),
				FansNum:        int64(anchorMap[int(recLives[idx].Anchorid)].FansNum),
				Hot:            int64(anchorMap[int(recLives[idx].Anchorid)].Hot),
				IsSubscription: int32(anchorMap[int(recLives[idx].Anchorid)].IsSubscription),
				Living:         int32(anchorMap[int(recLives[idx].Anchorid)].Living),
			}
		}
	}
	// }
	var liveNotice = models_live.LiveNotice{}
	liveNotice, _ = cache.LiveNotice(int(r.Anchorid))

	// 是否开启竞猜
	if check > 0 {
		var _guess int
		err = global2.Guess().Model(&models_guess.Guess{}).Where("live_id=?", live.Liveid).Pluck("id", &_guess).Error
		if err != nil {
			global2.Log.Warnf("rpc:LiveData:", err.Error())
		}
		if _guess > 0 {
			global.GetRds().Set(_const.ACTION_GUESS_TO_LOGIN+r.DeviceInfo, live.Liveid, 3600*time.Second)
		}
	}

	var match *protobuf.Match
	if check > 0 {
		match = cache.MatchData(int(live.Matchid))
	}
	// ip to 16hex
	return &protobuf.LiveDataResp{
		Live:             live,
		CategoryName:     cateName,
		Anchor:           &anchor,
		RecLives:         recLives,
		FansCount:        int64(anchor.FansNum),
		LiveNotice:       liveNotice.Content,
		UserLocal:        fmt.Sprintf("%v", ip2int(net.ParseIP(r.ClientIp))),
		Math:             match,
		LocalDb:          fmt.Sprintf("userArea:%+v, ip 16hex:%v", userArea, hex.EncodeToString([]byte(r.ClientIp))),
		Advertising:      anchorData.Advertising, //广告词
		ContactName_1:    liveNotice.ContactName1,
		ContactAddress_1: liveNotice.ContactAddress1,
		ContactName_2:    liveNotice.ContactName2,
		ContactAddress_2: liveNotice.ContactAddress2,
		ContactName_3:    liveNotice.ContactName3,
		ContactAddress_3: liveNotice.ContactAddress3,
		MainContent:      liveNotice.MainContent,
	}, nil
}

func getAnchors(guildid int, ids []int, order string, page, size int) (map[int]*api_models.Anchor, error) {
	fName := "GetAnchor"
	var err error
	result := make([]*api_models.Anchor, 0)
	partUsers := make([]*models_main.PartUser, 0)

	if guildid > 0 {
		partUsers, err = db_main.GetPartUsersParam(map[string]interface{}{"guildid": guildid}, order, page, size)
	} else if len(ids) > 0 {
		partUsers, err = db_main.GetPartUsersParam(map[string]interface{}{"id": map[string]interface{}{"in": ids}}, "", 0, 0)
	} else {
		partUsers, err = db_main.GetPartUsersParam(map[string]interface{}{"is_anchor": 1}, order, page, size)
	}
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	err = copier.Copy(&result, &partUsers)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	for _, v := range result {
		//for _, l := range fansNum {
		//	if v.Id == l.ID {
		//		v.FansNum = int(l.FansNum)
		//	}
		//}
		v.FansNum = cache.GetFansCount(v.Id)
	}

	resultMap := make(map[int]*api_models.Anchor)
	for idx := range result {
		resultMap[result[idx].Id] = result[idx]
	}

	return resultMap, nil
}

func ip2int(ip net.IP) uint32 {
	if len(ip) == 16 {
		return binary.BigEndian.Uint32(ip[12:16])
	}
	return binary.BigEndian.Uint32(ip)
}

func (s *Server) AnchorDetail(ctx context.Context, r *protobuf.AnchorDetailReq) (*protobuf.AnchorDetailResp, error) {
	var res = protobuf.AnchorDetailResp{}
	anchorData, err := cache.GetUserFullInfo(int(r.Id)) //repository.GetUserParam(map[string]interface{}{"id": r.Anchorid})
	if err != nil {
		return nil, err
	}

	res.Id = int64(anchorData.Id)
	res.Avatar = anchorData.Avatar
	res.Intro = anchorData.Intro
	res.Banner = anchorData.Banner
	res.Name = anchorData.NickName

	if r.Uid > 0 {
		attentedIds := cache.GetUserAttentAnchorIds(int(r.Uid))
		global2.Log.Debugf("attentedIds:%v\n", attentedIds)
		if string2.IntIsInSlice(attentedIds, int(r.Id)) {
			res.IsAttent = 1
		}
	} else {
		res.IsAttent = 0
	}

	res.FansCount = int64(cache.GetFansCount(int(r.Id)))

	return &res, nil
}

func (s *Server) AnchorReplay(ctx context.Context, r *protobuf.AnchorReplayReq) (*protobuf.AnchorReplayResp, error) {
	anchorData, err := cache.GetUserFullInfo(int(r.Id))
	if err != nil {
		return &protobuf.AnchorReplayResp{}, err
	}
	if anchorData.ReplayShow != 1 {
		return &protobuf.AnchorReplayResp{}, nil
	}

	var res = []*models_main.Video{}
	var limit, offset int
	var total int64
	limit, offset = util.Pagiation(int(r.Page), int(r.Limit))

	if r.Id <= 0 {
		return &protobuf.AnchorReplayResp{}, errors.New("params error")
	}

	err = global.GetR().Model(&models_main.Video{}).Where("anchor_id=?", r.Id).Count(&total).Offset(offset).Limit(limit).Order("id desc").Scan(&res).Error
	if err != nil {
		return &protobuf.AnchorReplayResp{}, err
	}

	var liveHistory = []models_live.LiveHistory{}

	var streams []string
	for _, v := range res {
		streams = append(streams, v.Stream)
	}

	err = global.Live().Model(&models_live.LiveHistory{}).Where("stream in ?", streams).Scan(&liveHistory).Error
	if err != nil {
		return &protobuf.AnchorReplayResp{}, err
	}

	var ret = protobuf.AnchorReplayResp{
		Total: total,
	}

	for _, v := range res {
		var thumb string
		var title string
		var hot int64
		for _, j := range liveHistory {
			if v.Stream == j.Stream {
				thumb = j.Thumb
				title = j.Title
				hot = int64(j.Hot)
			}
		}
		ret.List = append(ret.List, &protobuf.AnchorReplay{
			Id:        v.Id,
			AnchorId:  int64(anchorData.Id),
			Name:      anchorData.NickName,
			Avatar:    anchorData.Avatar,
			LiveThumb: thumb,
			LiveTitle: title,
			Date:      v.CreateTime,
			PlayUrl:   v.PlayURL,
			Duration:  v.Duration,
			Hot:       hot,
		})
	}

	return &ret, nil
}
